﻿using System;
using System.Collections.Generic;
using System.CodeDom;
using BMC.ARSystem;

namespace Wicresoft.EKA.NRemedy.CodeGenerate
{
    public class GenerateProperty : GeneratePropertyBase
    {
        public override void Create(CodeTypeDeclaration classType, string propertyName,
            string propertyType, Limit limit, Dictionary<string, object> attributePropertyValues)
        {
            if (classType == null) throw new ArgumentNullException("classType");
            if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException("propertyName");
            if (string.IsNullOrEmpty(propertyType)) throw new ArgumentNullException("propertyType");
            if (attributePropertyValues == null) throw new ArgumentNullException("attributePropertyValues");

            base.Create(classType, propertyName, propertyType, limit, attributePropertyValues);

            GenerateNameResolver gnr = new GenerateNameResolver();
            CodeMemberProperty _property = new CodeMemberProperty();
            _property.Name = propertyName;
            _property.Type = new CodeTypeReference(propertyType);

            _property.Attributes = MemberAttributes.Public | MemberAttributes.Final;

            _property.GetStatements.Add(new CodeVariableDeclarationStatement(typeof(object), "temp", new CodeIndexerExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "ValueList"),
                new CodePrimitiveExpression(attributePropertyValues["DatabaseID"]))));

            //如果想做成Nullable的 可以直接将return default(T)换为NULL，OR直接用NUllAble 强制转换。 
            _property.GetStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("temp"), CodeBinaryOperatorType.ValueEquality,
               new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("System.DBNull"), "Value")), CodeBinaryOperatorType.BooleanOr,
               new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("temp"), CodeBinaryOperatorType.ValueEquality,
               new CodePrimitiveExpression(null))), new CodeMethodReturnStatement(new CodeDefaultValueExpression(_property.Type))));

            _property.GetStatements.Add(
                new CodeMethodReturnStatement(new CodeCastExpression(propertyType, new CodeVariableReferenceExpression("temp"))));

            _property.SetStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertySetValueReferenceExpression(), CodeBinaryOperatorType.ValueEquality,
  new CodePrimitiveExpression(null)), new CodeStatement[] { new CodeAssignStatement(new CodeIndexerExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "ValueList"),
                new CodePrimitiveExpression(attributePropertyValues["DatabaseID"])),
                new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("System.DBNull"), "Value"))},
              new CodeStatement[] { new CodeAssignStatement(new CodeIndexerExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "ValueList"),
                new CodePrimitiveExpression(attributePropertyValues["DatabaseID"])),
                new CodePropertySetValueReferenceExpression())}));

            classType.Members.Add(_property);

        }
    }
}
